﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using jaysJourney_v01.Common;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using jaysJourney_v01.Utils;
using Microsoft.Xna.Framework.Input;
using System.Diagnostics;
using jaysJourney_v01.Utils.Levels;

namespace jaysJourney_v01.States
{
    class LoadWorldState : State
    {
        /**
         * MEMBER VARIABLES
         * */

        // From Parent

        private SpriteBatch mainSpriteBatch;

        // Common

        private List<Level> worldList;
        private int curPage;
        private int maxPages;
        private int worldsPerPage = 10;

        private SpriteFont textFont;

        private Texture2D interfaceBG;

        private bool loading;
        private bool loading2;
        public bool loadworldoverview;
        private Texture2D loadingscreen;
        private string clickname;

        private String[] Sizenames = { "Tiny", "Small", "Medium", "Big", "Huge" };

        // Buttons
        private InputGroup menuButtonGroup;
        

        /**
         * METHODS
         * */

        // Empty Constructor

        public LoadWorldState(String name, StateManager stateManager) : base(name, stateManager) { }

        // init first time

        public override void initialize()
        {
            mainSpriteBatch = this.parentSpriteBatch;

            this.interfaceBG = this.getGame().Content.Load<Texture2D>(@"Textures\Interface\Stage_Overview");

            this.menuButtonGroup = new InputGroup(this, this.mainSpriteBatch);

            this.textFont = this.getGame().Content.Load<SpriteFont>(@"Fonts\Segoe UI Mono");
            this.loadingscreen = this.getGame().Content.Load<Texture2D>(@"Textures\Preloader\loadingscreen");

        }

        // MAIN UPDATE METHOD

        public override void update(GameTime gameTime)
        {
            // update buttons
            Button click = this.menuButtonGroup.update(gameTime);

            //load a world after loadingscreen
            if (loading2)
            {
                loading2 = false;
                switch (clickname)
                {
                    case "lvl1": loadWorld(0 + (curPage * worldsPerPage)); break;
                    case "lvl2": loadWorld(1 + (curPage * worldsPerPage)); break;
                    case "lvl3": loadWorld(2 + (curPage * worldsPerPage)); break;
                    case "lvl4": loadWorld(3 + (curPage * worldsPerPage)); break;
                    case "lvl5": loadWorld(4 + (curPage * worldsPerPage)); break;
                    case "lvl6": loadWorld(5 + (curPage * worldsPerPage)); break;
                    case "lvl7": loadWorld(6 + (curPage * worldsPerPage)); break;
                    case "lvl8": loadWorld(7 + (curPage * worldsPerPage)); break;
                    case "lvl9": loadWorld(8 + (curPage * worldsPerPage)); break;
                    case "lvl10": loadWorld(9 + (curPage * worldsPerPage)); break;
                    case "BACK": this.getStateManager().setActiveState("menuState"); break;
                    case "pagePrev": if (this.curPage > 0) this.curPage--; this.addButtons(); break;
                    case "pageNext": if (this.curPage < this.maxPages) this.curPage++; this.addButtons(); break;
                }
            }
            //action after loadingscreen
            if (loading)
            {
                loading = false;
                this.loadWorldOverview();
            }
            //trigger loadingscreen & prepare for action
            if (loadworldoverview)
            {
                loadworldoverview = false;
                loading = true;
                
            }
            

           

            // handle button clicks
            if (click != null)
            {
                clickname = click.getName();
                loading2 = true;
            }
        }

        // MAIN DRAW

        public override void draw(GameTime gameTime)
        {
            // draw bg
            this.mainSpriteBatch.Draw(this.getGame().menuBg, new Rectangle(0, 0, this.getGame().GraphicsDevice.Viewport.Width, this.getGame().GraphicsDevice.Viewport.Height), new Rectangle(0, 0, this.getGame().menuBg.Width, this.getGame().menuBg.Height), Color.White);

            // draw interface bg
            this.mainSpriteBatch.Draw(this.interfaceBG, new Rectangle((this.getGame().GraphicsDevice.Viewport.Width / 2) - this.interfaceBG.Width / 2, 0, this.interfaceBG.Width, this.interfaceBG.Height), new Rectangle(0, 0, this.interfaceBG.Width, this.interfaceBG.Height), Color.White);

            // draw titles
            this.mainSpriteBatch.DrawString(this.textFont, "WORLDNAME", new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) - 410, 50), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
            this.mainSpriteBatch.DrawString(this.textFont, "STNG", new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) - 180, 50), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
            this.mainSpriteBatch.DrawString(this.textFont, "SIZE", new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) - 110, 50), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
            this.mainSpriteBatch.DrawString(this.textFont, "NUMPLAYS", new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 20, 50), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
            this.mainSpriteBatch.DrawString(this.textFont, "RATING", new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 150, 50), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
            this.mainSpriteBatch.DrawString(this.textFont, "CREATION DATE", new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 250, 50), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);

            // draw buttons
            this.menuButtonGroup.draw(gameTime);

            // draw List
            this.displayWorldList();
            if (loading||loadworldoverview||loading2) this.mainSpriteBatch.Draw(this.loadingscreen, new Rectangle((this.getGame().GraphicsDevice.Viewport.Width / 2) - this.loadingscreen.Width / 2, (this.getGame().GraphicsDevice.Viewport.Height / 2) - this.interfaceBG.Height / 2, this.loadingscreen.Width, this.loadingscreen.Height), new Rectangle(0, 0, this.loadingscreen.Width, this.loadingscreen.Height), Color.White);

        }

        public override void onEnterState()
        {
        }

        // load worldOverview
        // function has been made private to trigger a loadingscreen, instead set the public bool loadworldoverview true 
        private void loadWorldOverview()
        {
            // Load Worlds
            this.worldList = WebLoader.loadAllMaps(this.getStateManager().getGame().activePlayer.getCurrentLevel());

            if (this.worldList != null)
            {
                // Pages
                this.curPage = 0;
                this.maxPages = (this.worldList.Count / this.worldsPerPage);
                if (this.worldList.Count % this.worldsPerPage == 0) this.maxPages--; // round down
            }
            else
            {
                // Error database connection
                this.getGame().pushMessage("Could not connect to the Database!", true);
                this.menuButtonGroup.resetInputField();
                this.getStateManager().setActiveState("menuState");
            }

            // redraw buttons
            this.addButtons();
        }

        // DisplayWorldList

        private void displayWorldList()
        {
            if (this.worldList != null)
            {
                // Draw List
                int counter = 0;
                while (counter < worldsPerPage && (counter + (this.curPage * this.worldsPerPage)) < this.worldList.Count)
                {
                    this.mainSpriteBatch.DrawString(this.textFont, this.worldList[counter + (this.curPage * this.worldsPerPage)].getLevel(), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) - 410, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
                    this.mainSpriteBatch.DrawString(this.textFont, this.worldList[counter + (this.curPage * this.worldsPerPage)].getSetting(), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) - 180, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
                    this.mainSpriteBatch.DrawString(this.textFont, getSizeName(this.worldList[counter + (this.curPage * this.worldsPerPage)].getSize()), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) - 110, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
                    this.mainSpriteBatch.DrawString(this.textFont, this.worldList[counter + (this.curPage * this.worldsPerPage)].getNumStarts().ToString(), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 20, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
                    this.mainSpriteBatch.DrawString(this.textFont, this.worldList[counter + (this.curPage * this.worldsPerPage)].getCurRating().ToString(), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 150, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
                    this.mainSpriteBatch.DrawString(this.textFont, this.worldList[counter + (this.curPage * this.worldsPerPage)].getWorldCreation(), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 250, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);

                    counter++;
                }

                this.mainSpriteBatch.DrawString(this.textFont, "Page " + (this.curPage + 1) + " / " + (this.maxPages + 1), new Vector2((this.getGame().GraphicsDevice.Viewport.Width / 2) + 250, 100 + 50 * counter), Color.White, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 1f);
            }
        }

        private String getSizeName(String size){
            switch(size){
            case "060060":return Sizenames[0];
            case "050050": return Sizenames[0];
            case "070070": return Sizenames[1];
            case "090090": return Sizenames[1];
            case "120120": return Sizenames[2];
            case "150150": return Sizenames[3];
            case "200200": return Sizenames[4];
            }
            return "";
        }

        // Load chosen world

        private void loadWorld(int lvlID)
        {
            // get playstate
            PlayState playState = ((PlayState)this.getStateManager().getState("playState"));

            // load world
            String world = WebLoader.loadWorld(this.worldList[lvlID].getLevel());

            // update currentWorld
            playState.getLevel().curWorldData = world;

            playState.setLvlData(this.worldList[lvlID]);

            // load personal best
            playState.getLvlData().setPersonalBest(WebLoader.getPersonalBest(playState.getLvlData().getLevel(), this.getGame().activePlayer.getUsername()));

            // prepare world
            playState.jay.newPosition = ((PlayState)this.getStateManager().getState("playState")).getLevel().StartPoint * CONST.BLOCKSIZE;
            playState.resetLevel();

            // see details of world
            this.getStateManager().setActiveState("curWorldDetailState");
        }

        // add btns

        private void addButtons()
        {
            this.menuButtonGroup = new InputGroup(this, this.mainSpriteBatch);

            if (this.worldList != null)
            {
                int counter = 0;
                while (counter < worldsPerPage && (counter + (this.curPage * this.worldsPerPage)) < this.worldList.Count)
                {
                    this.menuButtonGroup.addButton(new Button(this, "lvl" + (counter + 1), @"Textures\Interface\arrow_btn", @"Textures\Interface\arrow_btn_ac", (this.getGame().GraphicsDevice.Viewport.Width / 2) - 490, 90 + (50 * counter), Color.White, false, false));
                    counter++;
                }

                this.menuButtonGroup.addButton(new Button(this, "pagePrev", @"Textures\Interface\minus_btn", @"Textures\Interface\minus_btn_ac", (this.getGame().GraphicsDevice.Viewport.Width / 2) + 250, 650, Color.White, false, false));
                this.menuButtonGroup.addButton(new Button(this, "pageNext", @"Textures\Interface\plus_btn", @"Textures\Interface\plus_btn_ac", (this.getGame().GraphicsDevice.Viewport.Width / 2) + 310, 650, Color.White, true, false));
            }

            this.menuButtonGroup.addButton(new Button(this, "BACK", @"Textures\Interface\back_btn", @"Textures\Interface\back_btn_ac", 20, this.getGame().GraphicsDevice.Viewport.Height - 74, Color.White, false, false));
        }
    }
}
